<template>
  <div class="editor-input-border">
    <template v-if="mode === 'DESIGN'">
      <Toolbar class="editor-input-border" :editor="editorDesignInstance" :defaultConfig="toolbarConfig" :mode="editorModel" />
      <Editor
        style="height: 500px; overflow-y: hidden"
        :defaultConfig="editorConfig"
        :mode="editorModel"
        @onCreated="editorDesignCreated"
      />
    </template>
    <template v-else>
      <Toolbar class="editor-input-border" :editor="editorInstance" :defaultConfig="toolbarConfig" :mode="editorModel" />
      <Editor
        style="height: 500px; overflow-y: hidden"
        :defaultConfig="editorConfig"
        v-model.trim="_value"
        :mode="editorModel"
        @onChange="editorChange"
        @onCreated="editorCreated"
      />
    </template>
  </div>
</template>

<script setup>
import { computed, getCurrentInstance, onUnmounted, ref, useAttrs } from "vue";
import { dayjs } from "element-plus";
import { isEmpty } from "lodash";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import "@wangeditor/editor/dist/css/style.css";
import { signatureUrl, setACL, fileReadRole } from "@/utils/aliOssUpload";
import defaultConfig from "@/settings";
import useMultipartOssStore from "@/store/modules/multipartOss";

const { proxy } = getCurrentInstance();
const $attrs = useAttrs();
const props = defineProps({
  mode: {
    type: String,
    default: "DESIGN"
  },
  required: {
    type: Boolean,
    default: false
  },
  readonly: {
    type: Boolean,
    default: false
  },
  modelValue: {
    type: String,
    default: ""
  },
  placeholder: {
    type: String,
    default: "请输入内容"
  }
});
const emit = defineEmits(["update:modelValue"]);
const multipartOssStore = useMultipartOssStore();

const _value = computed({
  get() {
    return props.modelValue;
  },
  set(val) {
    emit("update:modelValue", val);
  }
});

const editorInstance = ref(null);
const editorDesignInstance = ref(null);
const toolbarConfig = ref({
  excludeKeys: ["insertImage", "insertVideo", "uploadVideo", "editVideoSize", "|", "fullScreen"]
});
const getSuffix = file => {
  return file.type.slice(file.type.lastIndexOf("/") + 1);
};
const getFileName = fileName => {
  return fileName.slice(0, fileName.lastIndexOf("."));
};

const editorConfig = ref({
  placeholder: "请输入内容...",
  readOnly: false,
  MENU_CONF: {
    uploadImage: {
      customUpload: (file, insertFn) => {
        const nowTime = dayjs().format("YYYY-MM-DD HH:mm:ss");
        let fileName = file.name;
        fileName = `${getFileName(fileName)}-${nowTime}.${getSuffix(file)}`;
        file = new File([file], fileName, { type: file.type });
        let objName = `${defaultConfig.fileFolder}/${file.name}`;
        multipartOssStore
          .submit(objName, file, file.uid)
          .then(async res => {
            await setACL(objName, fileReadRole.publicRead);
            const fileUrl = await signatureUrl(objName);
            res.fileUrl = fileUrl ? `${fileUrl}`.split("?")[0] : "";
            insertFn(res.fileUrl, "", res.fileUrl);
          })
          .catch(err => {
            console.log(err);
            alert(JSON.stringify(err));
          });
      }
    }
  }
});
const editorModel = ref("default");

const editorCreated = editor => {
  editorInstance.value = Object.seal(editor);
  $attrs.disabled && disableEditor();
};
const getText = str => {
  return str
    .replace(/<[^<p>]+>/g, "")
    .replace(/<[</p>$]+>/g, "")
    .replace(/&nbsp;/gi, "")
    .replace(/<[^<br/>]+>/g, "");
};
const editorChange = () => {
  const val = editorInstance.value.getHtml();
  const text = getText(val);
  emit("update:modelValue", !text ? "" : val);
};
const disableEditor = () => {
  editorInstance.value.disable();
};
const editorDesignCreated = editor => {
  editorDesignInstance.value = Object.seal(editor);
  disableDesignEditor();
};
const disableDesignEditor = () => {
  editorDesignInstance.value.disable();
};

onUnmounted(() => {
  const editor = editorInstance.value;
  if (!editor) return;
  editor.destroy();
});

if (isEmpty(_value.value) && !$attrs.disabled) {
  _value.value = $attrs.defaultValue;
}
</script>

<style lang="less">
.editor-input-border {
  width: 100%;
  border: 1px solid #ccc;
}

button[data-menu-key="group-video"] {
  display: none;
}
</style>
